﻿using System;
using System.Collections.Generic;
using System.Numerics;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// Enumerable扩展类
    /// </summary>
    unsafe public partial class EnumerableEx
    {
        #region 升序

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<char> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            char temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<sbyte> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            sbyte temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<byte> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            byte temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<short> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            short temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<ushort> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            ushort temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<int> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            int temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<uint> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            uint temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<long> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            long temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<ulong> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            ulong temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<float> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            float temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<double> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            double temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<decimal> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            decimal temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<BigInteger> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            BigInteger temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

#if CORE

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<Int128> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            Int128 temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void Order(Span<Half> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            Half temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] < data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }
#endif

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <typeparam name="T">数据源类型</typeparam>
        /// <param name="data">要排序的数据源</param>
        /// <param name="comparer">比较器</param>
        public static void Order<T>(Span<T> data, IComparer<T> comparer) where T : struct
        {
            if (data.Length < 2)
            {
                return;
            }

            T temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (comparer.Compare(data[j], data[i]) < 0)
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据升序排序
        /// </summary>
        /// <typeparam name="T">数据源类型</typeparam>
        /// <typeparam name="TKey">排序key</typeparam>
        /// <param name="data">要排序的数据源</param>
        /// <param name="keySelector">key选择器</param>
        public static void Order<T, TKey>(Span<T> data, Func<T, TKey> keySelector)
            where T : struct
            where TKey : IComparable<TKey>
        {
            if (data.Length < 2)
            {
                return;
            }

            if (keySelector == null)
            {
                throw new ArgumentNullException(nameof(keySelector));
            }

            TKey key;
            T temp;
            for (int i = 0; i < data.Length; i++)
            {
                key = keySelector(data[i]);
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (keySelector(data[j]).CompareTo(key) < 0)
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        #endregion

        #region 降序

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<char> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            char temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<sbyte> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            sbyte temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<byte> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            byte temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<short> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            short temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<ushort> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            ushort temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<int> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            int temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<uint> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            uint temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<long> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            long temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<ulong> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            ulong temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<float> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            float temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<double> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            double temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<decimal> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            decimal temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<BigInteger> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            BigInteger temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

#if CORE

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<Int128> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            Int128 temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <param name="data">要排序的数据源</param>
        public static void OrderDescending(Span<Half> data)
        {
            if (data.Length < 2)
            {
                return;
            }

            Half temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (data[j] > data[i])
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

#endif

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <typeparam name="T">数据源类型</typeparam>
        /// <param name="data">要排序的数据源</param>
        /// <param name="comparer">比较器</param>
        public static void OrderDescending<T>(Span<T> data, IComparer<T> comparer) where T : struct
        {
            if (data.Length < 2)
            {
                return;
            }

            T temp;
            for (int i = 0; i < data.Length; i++)
            {
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (comparer.Compare(data[j], data[i]) > 0)
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        /// <summary>
        /// 数据降序排序
        /// </summary>
        /// <typeparam name="T">数据源类型</typeparam>
        /// <typeparam name="TKey">排序key</typeparam>
        /// <param name="data">要排序的数据源</param>
        /// <param name="keySelector">key选择器</param>
        public static void OrderDescending<T, TKey>(Span<T> data, Func<T, TKey> keySelector)
            where T : struct
            where TKey : IComparable<TKey>
        {
            if (data.Length < 2)
            {
                return;
            }

            if (keySelector == null)
            {
                throw new ArgumentNullException(nameof(keySelector));
            }

            TKey key;
            T temp;
            for (int i = 0; i < data.Length; i++)
            {
                key = keySelector(data[i]);
                for (int j = i + 1; j < data.Length; j++)
                {
                    if (keySelector(data[j]).CompareTo(key) > 0)
                    {
                        temp = data[i];
                        data[i] = data[j];
                        data[j] = temp;
                    }
                }
            }
        }

        #endregion
    }

}
